/* This source file is part of the Delectable Engine.
 * For the latest info, please visit http://delectable.googlecode.com/
 *
 * Copyright (c) 2009-2010 Ryan Chew
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *    http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @file GameWindow.cpp
 * @brief Application window.
 */

// Delectable Headers //
#include "dbl/Core/GameWindow.h"
#include "IPlatformWindow.h"

// External Dependencies //
#include <windows.h>

using namespace dbl;

GameWindow::GameWindow( cbl::Game & game )
: cbl::GameComponent( game )
, mPlatformWindow( NULL )
{
	this->UpdateOrder = INT_MIN; // Ensure that all window events come as early as possible.
}

GameWindow::GameWindow( cbl::Game & game, const GameWindowSettings & settings )
: cbl::GameComponent( game )
, mSettings( settings )
, mPlatformWindow( NULL )
{
}

GameWindow::~GameWindow()
{
	CBL_DELETE( mPlatformWindow );
}

GameWindowHandle GameWindow::GetGameWindowHandle()
{
	CBL_ASSERT_TRUE( mPlatformWindow );
	return mPlatformWindow->GetHandle();
}

void GameWindow::Initialise( void )
{
	CBL_ASSERT( mPlatformWindow == NULL, "Platform window has already been created!" );
	mPlatformWindow = IPlatformWindow::Create( this, mSettings );

	OnWindowCreated();
}

void GameWindow::Shutdown( void )
{
	CBL_ASSERT_TRUE( mPlatformWindow );

	OnWindowDestroyed();

	CBL_DELETE( mPlatformWindow );
}

void GameWindow::Update( const cbl::GameTime & )
{
	CBL_ASSERT_TRUE( mPlatformWindow );
	mPlatformWindow->ProcessWindowEvents();
}

void GameWindow::SetWindowSettings( const GameWindowSettings & settings )
{
	CBL_ASSERT_TRUE( mPlatformWindow );

	mSettings = settings;
	mPlatformWindow->ResetTitle();
	mPlatformWindow->ResetSize();
	mPlatformWindow->ResetFullscreen();
	mPlatformWindow->ResetStyle();
}

void GameWindow::SetPosition( cbl::Uint32 x, cbl::Uint32 y )
{
	CBL_ASSERT_TRUE( mPlatformWindow );
	mPlatformWindow->SetPosition( x, y );
}

void GameWindow::SetSize( const GameWindowSize & size )
{
	CBL_ASSERT_TRUE( mPlatformWindow );
	mSettings.Dimensions = size;
	mPlatformWindow->ResetSize();
}

void GameWindow::SetTitle( const cbl::Char * const title )
{
	CBL_ASSERT_TRUE( mPlatformWindow );
	mSettings.Title = title;
	mPlatformWindow->ResetTitle();
}

void GameWindow::SetStyle( cbl::Uint32 style )
{
	CBL_ASSERT_TRUE( mPlatformWindow );
	mSettings.Style = style;
	mPlatformWindow->ResetStyle();
}

void GameWindow::SetFullscreen( bool state )
{
	if( state )
		mSettings.Style |= GameWindowStyle::Fullscreen;
	else if( mSettings.Style & GameWindowStyle::Fullscreen )
		mSettings.Style ^= GameWindowStyle::Fullscreen;

	mPlatformWindow->ResetFullscreen();
}

void GameWindow::Show( bool state )
{
	CBL_ASSERT_TRUE( mPlatformWindow );
	mPlatformWindow->Show( state );
}

void GameWindow::ShowCursor( bool state )
{
	CBL_ASSERT_TRUE( mPlatformWindow );
	mPlatformWindow->ShowCursor( state );
}
